package Controladores;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;

import Utilities.EstabelecimentoCombo;
import Utilities.EventoCombo;
import Utilities.LinhaCombo;
import Utilities.LugarCombo;
import Utilities.PratoCombo;
import Utilities.Utilizador;

public class DataBase {

	private static DataBase instance = null;

	private Connection conn = null;

	// para enviar cenas para a base de dados
	private PreparedStatement statement = null;

	// para os resultados das querys
	private ResultSet resultSet = null;

	protected DataBase() {
		String db = "eatDrinkGrupo8";
		String dbUrl = "jdbc:sqlanywhere:Tds:localhost:2638?eng=" + db;
		try {
			conn = DriverManager.getConnection(dbUrl, "dba", "sql");
		} catch (SQLException e) {
		}
	}

	public static DataBase getInstance() {
		if (instance == null) {
			instance = new DataBase();
		}
		return instance;
	}

	public ArrayList<PratoCombo> getPratos(Object estabelecimento) {
		ArrayList<PratoCombo> pratos = new ArrayList<PratoCombo>();
		try {
			String query = "SELECT Prato.idPrato, Prato.descricao FROM Prato ,Estabelecimento, menuDoEstabelecimento "
					+ "WHERE Estabelecimento.designacao='"
					+ (String) estabelecimento
					+ "'"
					+ " AND menuDoEstabelecimento.idEstabelecimento = Estabelecimento.idEstabelecimento"
					+ " AND menuDoEstabelecimento.idPrato = Prato.idPrato";
			statement = conn.prepareStatement(query);
			resultSet = statement.executeQuery(query);
			while (resultSet.next()) {
				Integer id = Integer.parseInt(resultSet.getString(1));
				pratos.add(new PratoCombo(id, resultSet.getString(2)));
			}

		} catch (SQLException e) {
			e.printStackTrace();
		}

		return pratos;

	}

	public ArrayList<LinhaCombo> filtrar(String utilizador,
			String estabelecimento, String prato, String comentario,
			Integer ratingI, boolean fotografia) {

		ArrayList<LinhaCombo> tabela = new ArrayList<LinhaCombo>();

		PreparedStatement filtrarStatement = null;
		ResultSet filtrarResultSet = null;

		String queryPratos = "SELECT DISTINCT Utilizador.nome, Estabelecimento.designacao, Prato.descricao, ComentarioAoPrato.nota, ComentarioAoPrato.comentario "
				+ "FROM Utilizador, Prato, ComentarioAoPrato, Estabelecimento, menuDoEstabelecimento "
				+ "WHERE Utilizador.email = ComentarioAoPrato.email AND ComentarioAoPrato.idPrato = Prato.idPrato "
				+ "AND Prato.idPrato = menuDoEstabelecimento.idPrato AND Estabelecimento.idEstabelecimento = menuDoEstabelecimento.idEstabelecimento";

		String queryEstabelecimentos = " UNION SELECT DISTINCT Utilizador.nome, Estabelecimento.designacao, NULL, ComentarioAoEstabelecimento.nota, ComentarioAoEstabelecimento.comentario "
				+ "FROM Utilizador, Prato, ComentarioAoPrato, Estabelecimento, ComentarioAoEstabelecimento "
				+ "WHERE Utilizador.email = ComentarioAoEstabelecimento.email AND ComentarioAoEstabelecimento.idEstabelecimento = Estabelecimento.idEstabelecimento ";

		if (!utilizador.equals("")) {
			queryPratos += " AND Utilizador.nome LIKE'%" + utilizador + "%'";
			queryEstabelecimentos += " AND Utilizador.nome LIKE'" + utilizador
					+ "%'";
		}

		if (ratingI != null) {
			queryPratos += " AND ComentarioAoPrato.nota = " + ratingI;
			queryEstabelecimentos += " AND ComentarioAoEstabelecimento.nota = "
					+ ratingI;
		}

		if (!comentario.equals("")) {
			queryPratos += " AND ComentarioAoPrato.comentario LIKE '%"
					+ comentario + "%'";
			queryEstabelecimentos += " AND ComentarioAoEstabelecimento.comentario LIKE '%"
					+ comentario + "%'";
		}

		// SELECIONAR APENAS(!) OS COMENTARIOS A PRATOS DE UM DADO
		// ESTABELECIMENTO (1,1)
		if (!estabelecimento.equals("") && !prato.equals("")) {

			queryPratos += " AND Estabelecimento.designacao LIKE '%"
					+ estabelecimento + "%' AND Prato.descricao LIKE '%"
					+ prato + "%'";
			queryEstabelecimentos = "";
			// SELECIONAR TODOS COMENTARIOS DE UM DADO ESTABELECIMENTO
			// (INCLUINDO COMENTARIOS AOS SEUS PRATOS) (1,0)
		} else if (!estabelecimento.equals("") && prato.equals("")) {
			queryPratos += " AND Estabelecimento.designacao LIKE '%"
					+ estabelecimento + "%'";
			queryEstabelecimentos += " AND Estabelecimento.designacao LIKE '%"
					+ estabelecimento + "%'";
			// SELECIONAR TODOS OS PRATOS COM UM DADO NOME (0,1)
		} else if (estabelecimento.equals("") && !prato.equals("")) {
			queryPratos += " AND Prato.descricao LIKE '%" + prato + "%'";
			queryEstabelecimentos = "";
		}

		try {
			System.out.println("PRIMEIRA QUERY = " + queryPratos
					+ queryEstabelecimentos + ";");
			filtrarStatement = conn.prepareStatement(queryPratos
					+ queryEstabelecimentos + ";");
			filtrarResultSet = filtrarStatement.executeQuery(queryPratos
					+ queryEstabelecimentos + ";");

			while (filtrarResultSet.next()) {
				LinhaCombo l = new LinhaCombo(filtrarResultSet.getString(1),
						filtrarResultSet.getString(2),
						filtrarResultSet.getString(3),
						filtrarResultSet.getString(4),
						filtrarResultSet.getString(5), null);
				tabela.add(l);
			}

			for (LinhaCombo linhaCombo : tabela) {

				String fotoQuery = null;
				if (linhaCombo.getPrato() != null) {
					fotoQuery = "SELECT DISTINCT Fotografia.localizacao "
							+ "FROM Utilizador, Prato, ComentarioAoPrato, Estabelecimento, menuDoEstabelecimento, Fotografia "
							+ "WHERE Utilizador.nome = '"
							+ linhaCombo.getUtilizador()
							+ "' AND Utilizador.email = ComentarioAoPrato.email"
							+ " AND ComentarioAoPrato.comentario ='"
							+ linhaCombo.getComentario()
							+ "' AND ComentarioAoPrato.idPrato = Prato.idPrato"
							+ "	AND Prato.descricao = '"
							+ linhaCombo.getPrato()
							+ "' AND Prato.idPrato = menuDoEstabelecimento.idPrato"
							+ " AND Estabelecimento.designacao = '"
							+ linhaCombo.getEstabelecimento()
							+ "' AND Estabelecimento.idEstabelecimento = menuDoEstabelecimento.idEstabelecimento"
							+ " AND ComentarioAoPrato.nota = "
							+ linhaCombo.getAvaliacao()
							+ " AND Fotografia.idPrato = Prato.idPrato";

				} else {
					fotoQuery = "SELECT DISTINCT Fotografia.localizacao "
							+ "FROM Utilizador, Prato, ComentarioAoEstabelecimento, Estabelecimento, Fotografia "
							+ "WHERE  Estabelecimento.designacao = '"
							+ linhaCombo.getEstabelecimento()
							+ "' AND Fotografia.idEstabelecimento = Estabelecimento.idEstabelecimento";
				}
				PreparedStatement statement1 = null;
				ResultSet resultSet1 = null;

				if (fotoQuery != null) {
					statement1 = conn.prepareStatement(fotoQuery + ";");
					resultSet1 = statement1.executeQuery(fotoQuery + ";");
				}
				while (resultSet1.next()) {
					linhaCombo.setFotografia(resultSet1.getString(1));
				}
			}

			Iterator<LinhaCombo> l = tabela.iterator();
			while (l.hasNext()) {
				if (fotografia) {
					if (l.next().getFotografia() == null) {
						l.remove();
					}
				} else {
					if (l.next().getFotografia() != null) {
						l.remove();
					}
				}
			}

		} catch (SQLException e) {
			e.printStackTrace();
		}

		return tabela;

	}

	public ArrayList<EstabelecimentoCombo> getEstabelecimentos() {
		ArrayList<EstabelecimentoCombo> estabelecimentos = new ArrayList<EstabelecimentoCombo>();
		try {
			String query = "SELECT idEstabelecimento,designacao From Estabelecimento";
			statement = conn.prepareStatement(query);
			resultSet = statement.executeQuery(query);
			while (resultSet.next()) {
				Integer id = Integer.parseInt(resultSet.getString(1));
				estabelecimentos.add(new EstabelecimentoCombo(id, resultSet
						.getString(2)));
			}

		} catch (SQLException e) {
			e.printStackTrace();
		}

		return estabelecimentos;
	}

	public boolean inserirComentario(String email, Integer idEstabelecimento,
			Integer idPrato, String comentario, Integer avaliacao, Object prato) {
		try {
			if (prato == null || prato.equals("")) {
				statement = conn
						.prepareStatement("INSERT INTO ComentarioAoEstabelecimento Values (?,?,?,?,?)");
				statement.setString(2, email);
				statement.setInt(1, idEstabelecimento);
				statement.setString(3, comentario);
				statement.setInt(4, avaliacao);
				statement.setInt(5, 0);
			} else {
				statement = conn
						.prepareStatement("INSERT INTO ComentarioAoPrato Values (?,?,?,?)");
				statement.setString(1, email);
				statement.setInt(2, idPrato);
				statement.setString(3, comentario);
				statement.setInt(4, avaliacao);
			}
			int state = statement.executeUpdate();
			if (state == 1)
				return true;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;

	}

	public boolean apagarComentario(Integer idEstabelecimento, Integer idPrato,
			String email) {
		try {
			if (idPrato != null) {
				String query = "DELETE From ComentarioAoPrato WHERE idPrato="
						+ idPrato + " AND email= '" + email + "'";
				statement = conn.prepareStatement(query);
			} else {
				String query = "DELETE From ComentarioAoEstabelecimento WHERE idEstabelecimento="
						+ idEstabelecimento + "AND email= '" + email + "'";
				statement = conn.prepareStatement(query);
			}
			int state = statement.executeUpdate();
			if (state == 1)
				return true;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return false;

	}

	public boolean inserirAlteracao(Integer idEstabelecimento, Integer idPrato,
			String comentario, Integer avaliacao, String email) {
		try {
			if (idPrato != null) {
				String query = "UPDATE ComentarioAoPrato SET comentario='"
						+ comentario + "', nota=" + avaliacao
						+ " WHERE idPrato=" + idPrato + " AND email='" + email
						+ "'";
				statement = conn.prepareStatement(query);
			} else {
				String query = "UPDATE ComentarioAoEstabelecimento SET comentario= '"
						+ comentario
						+ "', nota="
						+ avaliacao
						+ " WHERE idEstabelecimento="
						+ idEstabelecimento
						+ " AND email= '" + email + "'";
				statement = conn.prepareStatement(query);
			}
			int state = statement.executeUpdate();
			if (state == 1)
				return true;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	public boolean verificarUtilizador(Utilizador utilizador) {
		try {
			String query = "SELECT email,senha,nome FROM Utilizador WHERE email='"
					+ utilizador.getEmail()
					+ "' AND senha = '"
					+ utilizador.getSenha() + "'";
			statement = conn.prepareStatement(query);
			resultSet = statement.executeQuery(query);
			while (resultSet.next()) {
				if (resultSet.getString(1).equals(utilizador.getEmail())
						&& resultSet.getString(2).equals(utilizador.getSenha())) {
					utilizador.setNome(resultSet.getString(3));
					return true;
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}

	public boolean verificarPermissoes(String email, String nome) {
		try {
			String query = "SELECT Utilizador.nome FROM Utilizador WHERE Utilizador.email= '"
					+ email + "'";
			statement = conn.prepareStatement(query);
			resultSet = statement.executeQuery(query);
			while (resultSet.next()) {
				if (resultSet.getString(1).equals(nome)) {
					return true;
				}
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	public String getNomeUtilizador(String email) {
		try {
			String query = "SELECT Utilizador.nome FROM Utilizador WHERE Utilizador.email= '"
					+ email + "'";
			statement = conn.prepareStatement(query);
			resultSet = statement.executeQuery(query);
			while (resultSet.next()) {
				return resultSet.getString(1);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public String getComentarioAoEstabelecimento(String email, Integer id) {
		try {
			String query = "SELECT ComentarioAoEstabelecimento.comentario FROM ComentarioAoEstabelecimento WHERE email = '"
					+ email + "' AND idEstabelecimento =" + id;
			statement = conn.prepareStatement(query);

			resultSet = statement.executeQuery(query);
			while (resultSet.next()) {
				return resultSet.getString(1);
			}

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public String getComentarioAoPrato(String email, Integer id) {
		try {
			String query = "SELECT ComentarioAoPrato.comentario FROM ComentarioAoPrato WHERE email = '"
					+ email + "' AND idPrato =" + id;
			statement = conn.prepareStatement(query);

			resultSet = statement.executeQuery(query);
			while (resultSet.next()) {
				return resultSet.getString(1);
			}

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public boolean apagarFoto(Integer idEstabelecimento, Integer idPrato,
			String email) {
		try {

			if (idPrato != null) {
				String query = "DELETE FROM Fotografia WHERE idPrato ="
						+ idPrato;
				statement = conn.prepareStatement(query);
				int state = statement.executeUpdate();
				if (state == 1)
					return true;

			} else if (idEstabelecimento != null) {
				String query = "DELETE FROM Fotografia WHERE idEstabelecimento ="
						+ idEstabelecimento;
				statement = conn.prepareStatement(query);
				int state = statement.executeUpdate();
				if (state == 1)
					return true;
			} else {
				String query = "DELETE FROM Utilizador WHERE email ='" + email
						+ "' "
						+ "DELETE FROM Fotografia WHERE emailutilizador ='"
						+ email + "'";
				System.out.println(query);
				statement = conn.prepareStatement(query);
				int state = statement.executeUpdate();
				if (state == 1)
					return true;
			}
		} catch (SQLException e) {
			e.printStackTrace();

		}
		return false;
	}

	public boolean inserirFotoPrato(Integer idEstabelecimento, Integer idPrato,
			String email, String directory) {
		try {
			Integer idFotografia = null;
			String query = "SELECT MAX(idFotografia) FROM Fotografia";
			resultSet = statement.executeQuery(query);
			while (resultSet.next()) {
				idFotografia = resultSet.getInt(1) + 1;
			}
			String query1 = "SELECT idFotografia FROM Fotografia WHERE idPrato = "
					+ idPrato;
			resultSet = statement.executeQuery(query1);
			while (resultSet.next()) {
				if (resultSet.getRow() != 0) {
					statement = conn
							.prepareStatement("UPDATE Fotografia SET localizacao = '"
									+ directory
									+ "' WHERE idPrato = "
									+ idPrato);
					statement.setInt(1, idFotografia);
					statement.setString(3, email);
					statement.setInt(2, idEstabelecimento);
					statement.setInt(4, idPrato);
					statement.setString(5, directory);

				} else {
					resultSet = statement.executeQuery(query);

					statement = conn
							.prepareStatement("INSERT INTO Fotografia Values (?,?,?,?,?)");
					statement.setInt(1, idFotografia);
					statement.setString(3, email);
					statement.setInt(2, idEstabelecimento);
					statement.setInt(4, idPrato);
					statement.setString(5, directory);
				}
			}
			int state = statement.executeUpdate();
			if (state == 1)
				return true;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return false;
	}

	public boolean inserirFotoEstabelecimento(Integer idEstabelecimento,
			String email, String directory) {
		try {
			Integer idFotografia = null;
			String query = "SELECT MAX(idFotografia) FROM Fotografia";
			resultSet = statement.executeQuery(query);
			while (resultSet.next()) {
				idFotografia = resultSet.getInt(1) + 1;
			}
			statement = conn
					.prepareStatement("INSERT INTO Fotografia Values (?,?,?,?,?)");
			statement.setInt(1, idFotografia);
			statement.setString(3, email);
			statement.setInt(2, idEstabelecimento);
			statement.setString(5, directory);
			statement.setString(4, null);
			;
			int state = statement.executeUpdate();
			if (state == 1)
				return true;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	public String getFotografia(Integer idEstabelecimento, Integer idPrato,
			String email) {
		try {
			if (idPrato != null) {
				String query = "SELECT localizacao FROM Fotografia WHERE idPrato="
						+ idPrato;
				resultSet = statement.executeQuery(query);
				while (resultSet.next()) {
					System.out.println(resultSet.getString(1));
					return resultSet.getString(1);
				}
			} else if (idEstabelecimento != null) {
				String query = "SELECT localizacao FROM Fotografia WHERE idEstabelecimento="
						+ idEstabelecimento;
				resultSet = statement.executeQuery(query);
				while (resultSet.next()) {
					return resultSet.getString(1);
				}
			} else {
				String query = "SELECT localizacao FROM Fotografia WHERE emailutilizador ='"
						+ email + "'";
				resultSet = statement.executeQuery(query);
				while (resultSet.next()) {
					return resultSet.getString(1);
				}
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public boolean inserirFotoUtilizador(String email, String directory) {
		try {
			Integer idFotografia = null;
			String query = "SELECT MAX(idFotografia) FROM Fotografia";
			resultSet = statement.executeQuery(query);
			while (resultSet.next()) {
				idFotografia = resultSet.getInt(1) + 1;
			}
			statement = conn
					.prepareStatement("INSERT INTO Fotografia Values (?,?,?,?,?)");
			statement.setInt(1, idFotografia);
			statement.setString(3, email);
			statement.setString(5, directory);
			statement.setString(4, null);
			System.out.println(query);
			int state = statement.executeUpdate();
			if (state == 1)
				return true;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	public Connection getConn() {
		return conn;
	}

	public ArrayList<EventoCombo> getEventos() {
		ArrayList<EventoCombo> listaEventos = new ArrayList<EventoCombo>();
		try {
			String query = "SELECT * FROM Evento";
			statement = conn.prepareStatement(query);
			resultSet = statement.executeQuery(query);
			while (resultSet.next()) {
				listaEventos.add(new EventoCombo(resultSet.getInt(1), resultSet
						.getString(3), resultSet.getString(4), resultSet
						.getString(5)));
			}
		} catch (SQLException e) {
			e.printStackTrace();

		}
		return listaEventos;
	}

	public ArrayList<LugarCombo> getLugares(int idEvento) {
		ArrayList<LugarCombo> listaLugares = new ArrayList<LugarCombo>();

		String query = "SELECT numeroLugar, estado FROM Evento WHERE idEvento = "
				+ idEvento;
		try {
			statement = conn.prepareStatement(query);
			resultSet = statement.executeQuery(query);
			while (resultSet.next()) {
				listaLugares.add(new LugarCombo(
						resultSet.getInt("numeroLugar"), resultSet
								.getInt("estado")));
			}

		} catch (SQLException e) {
			e.printStackTrace();
		}
		return listaLugares;
	}

	// public boolean mudaEstadoBilhete(String evento, Object lugar) {
	// String query1 = "SELECT nomeEvento FROM Evento for UPDATE";
	// try {
	// resultSet = statement.executeQuery(query1);
	// while (resultSet.next()) {
	// statement = conn
	// .prepareStatement("UPDATE evento SET estado = 1 Where nomeEvento = '"
	// + evento + "' AND numeroLugar = " + lugar);
	// }
	// int state = statement.executeUpdate();
	// if (state == 1)
	// return true;
	// } catch (SQLException e) {
	// // TODO Auto-generated catch block
	// e.printStackTrace();
	// }
	// return false;
	//
	// }
	public boolean mudaEstadoBilhete(String evento, Object lugar) {
		String query1 = "UPDATE evento SET estado = 1 Where nomeEvento = '"
				+ evento + "' AND numeroLugar = " + lugar;
		try {
			statement = conn.prepareStatement(query1);
			int state = statement.executeUpdate();
			if (state == 1)
				return true;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;

	}
}
